"""
Base classes for use in various execution contexts.
"""
class EventProcessor(object):
    _event_queue = None
    _active_events = None
    
    def __init__(self):
        self._event_queue = []
        self._active_events = []
        
    def _begin_events(self):
        for event in self._event_queue[:]:
            self._active_events.append(self._event_queue.pop(0))
            if event.blocking:
                break
                
    def tick(self, dt):
        while self._event_queue or self._active_events:
            for event in [e for e in self._active_events if not e.tick(dt)]:
                self._active_events.remove(event)
                
            if self._active_events:
                if not any(e for e in self._active_events if e.blocking): #Try to find the next blocker
                    self._begin_events()
                return True
            self._begin_events() #Ensure the queue is processed
        return False
        
class Event(object):
    """
    The prototypical event, defining the minimal interface an event needs to expose.
    """
    _blocking = True
    
    def __init__(self, blocking):
        self._blocking = blocking
        
    def _get_blocking(self):
        return self._blocking
    def _set_blocking(self, blocking):
        self._blocking = bool(blocking)
    blocking = property(_get_blocking, _set_blocking)
    
    def tick(self, dt):
        return False
        
class NoOpEvent(Event):
    _period = None
    
    def __init__(self, period):
        Event.__init__(self, blocking=True)
        self._period = period
        
    def tick(self, dt):
        self._period -= 1
        return self._period >= 0
        
